﻿//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Media;
using P2.Cuberry.Framework.BOLBase;
using P2.Cuberry.Framework.Security;
using P2.Cuberry.Framework.Helper;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Modules.Framework.UserGroup.DAL;


namespace P2.Cuberry.Modules.Framework.UserGroup.BusinessEntities
{
    public class UserGroupRight : BizObject, INotifyPropertyChanged
    {

        #region Constructors
                
        public UserGroupRight()
        {
            Modified = false;
        }
        
        
        public UserGroupRight(int keyUserGroupID, string keyModuleName, int keyAccessRight)
        {
            this._UserGroupID = keyUserGroupID;
            this._ModuleName = keyModuleName;
            this._AccessRight = keyAccessRight;
            FillMyObject();
            Modified = false;
        }


        public UserGroupRight(DAL.XSecUserRight UserGroupRight)
        {
            Load(UserGroupRight);
        }


        public UserGroupRight(DAL.MenuSubMenu msm, int userGroupID)
        {
            Load(msm, userGroupID);
        }

        #endregion


        #region Members

        private static DateTime _lastCacheUpdate = DateTime.MinValue;

        int _UserGroupID = -1;
        public int UserGroupID
        {
            get { return _UserGroupID; }
            set
            {
                if (value != _UserGroupID)
                {
                    _UserGroupID = value;
                    Modified = true;
                }
            }
        }
        
        int _AccessRight = -1;
        public int AccessRight
        {
            get { return _AccessRight; }
            set
            {
                if (value != _AccessRight)
                {
                    _AccessRight = value;
                    Modified = true;

                }
            }
        }

        string _ModuleName = String.Empty;
        public string ModuleName
        {
            get { return _ModuleName; }
            set
            {
                if (value != _ModuleName)
                {
                    _ModuleName = value;
                    Modified = true;


                }
            }
        }

        #endregion


        #region Computed Properties

        public Brush ActiveColor
        {
            get
            {
                if (_AccessRight > -1)
                {
                    if (_AccessRight == 0)
                    {
                        return Brushes.Red;
                    }
                    else if (_AccessRight == 1)
                    {
                        return Brushes.Yellow;
                    }
                    else
                    {
                        return Brushes.Green;
                    }
                }
                else
                {
                    return Brushes.White;
                }
            }
            set
            {
                if (value.Equals(Brushes.Red))
                {
                    _AccessRight = 0;

                }
                else if (value.Equals(Brushes.Yellow))
                {
                    _AccessRight = 1;
                    Modified = true;
                }
                else if (value.Equals(Brushes.Green))
                {
                    _AccessRight = 2;
                    Modified = true;
                }
                else
                {
                    _AccessRight = -1;
                }
                Modified = true;
                OnPropertyChanged("ActiveColor");
                OnPropertyChanged("AccessRight");

            }
        }
        
        #endregion


        #region UserGroupRight Items

        public UserGroup ParentUserGroup { set; get; }
        ObservableCollection<BusinessEntities.UserGroupSpecialRight> _userGroupSpecialRightItems = null;
        ObservableCollection<BusinessEntities.UserGroupSpecialRight> _userGroupSpecialRightDeletedItems = new ObservableCollection<UserGroupSpecialRight>();
        
        public ObservableCollection<BusinessEntities.UserGroupSpecialRight> UserGroupSpecialRightItems
        {
            get
            {
                if (_userGroupSpecialRightItems == null)
                {
                    RefreshUserGroupSpecialRightItems();
                }
                return _userGroupSpecialRightItems;
            }
            set
            {
                _userGroupSpecialRightItems = value;
            }
        }


        public void RefreshUserGroupSpecialRightItems()
        {
            try
            {
                var tempUserGroupSpecialRightItems = UserGroupSpecialRight.GetUserGroupSpecialRightsforHeader(this, null);
                if (_userGroupSpecialRightItems == null)
                {
                    _userGroupSpecialRightItems = tempUserGroupSpecialRightItems;
                    _userGroupSpecialRightItems.CollectionChanged += UserGroupSpecialRightItemsChanged;
                }
                else
                {
                    _userGroupSpecialRightItems.Clear();
                    foreach (var tempUserGroupSpecialRightItem in tempUserGroupSpecialRightItems)
                    {
                        _userGroupSpecialRightItems.Add(tempUserGroupSpecialRightItem);
                    }
                }
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public void UserGroupSpecialRightItemsChanged(Object sender, NotifyCollectionChangedEventArgs e)
        {
            try
            {
                if (e.Action == NotifyCollectionChangedAction.Add)
                {
                    foreach (var newItem in e.NewItems)
                    {
                        ((BusinessEntities.UserGroupSpecialRight)newItem).Modified = true;
                    }
                }
                if (e.Action == NotifyCollectionChangedAction.Remove)
                {
                    foreach (var deletedItems in e.OldItems)
                    {
                        UserGroupSpecialRight deletedUserGroupSpecialRightItem = (UserGroupSpecialRight)deletedItems;
                        UserGroupSpecialRightDeletedItems.Add(deletedUserGroupSpecialRightItem);
                    }
                }
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public ObservableCollection<BusinessEntities.UserGroupSpecialRight> UserGroupSpecialRightDeletedItems
        {
            get
            {
                return _userGroupSpecialRightDeletedItems;
            }
            set
            {
                _userGroupSpecialRightDeletedItems = value;
            }
        }
                        

        public static ObservableCollection<UserGroupRight> GetUserGroupRightsforHeader(UserGroup userGroup, PropertyChangedEventHandler onChange)
        {
            try
            {
                ObservableCollection<UserGroupRight> itemsCollection = new ObservableCollection<UserGroupRight>();
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (UserGroupDataContext db = new UserGroupDataContext(connectionString))
                {

                    var UserGroupRightItems = from ugrItem in db.XSecUserRights
                                              where ugrItem.UserGroupID == userGroup.UserGroupID
                                              select ugrItem;
                    List<string> smids = new List<string>();
                    if (UserGroupRightItems.Count() > 0)
                    {

                        foreach (var userGroupRightItem in UserGroupRightItems)
                        {
                            itemsCollection.Add(new UserGroupRight(userGroupRightItem) { ParentUserGroup = userGroup });
                            smids.Add(userGroupRightItem.ModuleName);
                        }
                    }
                    var MenuSubMenuItems = from msmitems in db.MenuSubMenus
                                           select msmitems;
                    if (MenuSubMenuItems.Count() > 0)
                        foreach (var msm in MenuSubMenuItems)
                        {
                            if (!smids.Contains(msm.ModuleName))
                            {
                                itemsCollection.Add(new UserGroupRight(msm, userGroup.UserGroupID) { ParentUserGroup = userGroup });
                            }
                        }
                }
                return itemsCollection;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", "UserGroupRight", System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        #endregion

        
        #region Read Operations

        public void Load(int userGroupId, string moduleName, int accessRight)
        {
            try
            {
                UserGroupID = userGroupId;
                this.ModuleName = moduleName;
                AccessRight = accessRight;
                if (UserGroupID > 0)
                {
                    FillMyObject();
                }
                else
                {
                    Load(null);
                }
                Modified = false;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public void Load(DAL.XSecUserRight sourceEntity)
        {
            try
            {
                if (sourceEntity != null)
                {
                    this.UserGroupID = sourceEntity.UserGroupID;
                    this.ModuleName = sourceEntity.ModuleName;
                    this.AccessRight = sourceEntity.AccessRight;

                    //Default Fields                
                    this.CreatedBy = sourceEntity.CreatedBy;
                    this.CreatedOn = sourceEntity.CreatedOn;
                    this.EditedBy = sourceEntity.EditedBy;
                    this.EditedOn = sourceEntity.EditedOn;
                    //this.Timestamp = sourceEntity.TStamp;
                    //this.StatusID = sourceEntity.StatusID.GetValueOrDefault(P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName).StatusID);
                }
                else
                {
                    this.UserGroupID = -1;
                    this.ModuleName = String.Empty;
                    this.AccessRight = -1;
                    this.ModuleName = String.Empty;

                    //Default Fields
                    this.CreatedBy = String.Empty;
                    this.EditedBy = String.Empty;
                    //P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus initStatus = P2.Cuberry.Framework.Helper.Workflows.WorkflowStatus.GetInitialStatus(this.EntityName);
                    //this.StatusID = initStatus.StatusID;
                }
                Modified = false;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        public void Load(DAL.MenuSubMenu msm, int userGroupID)
        {
            try
            {
                if (msm != null)
                {
                    this.UserGroupID = userGroupID;
                    this.ModuleName = msm.ModuleName;
                    this.AccessRight = 0;
                }
                else
                {
                    this.UserGroupID = -1;
                    this.ModuleName = String.Empty;
                    this.AccessRight = -1;
                    this.ModuleName = String.Empty;
                }
                Modified = false;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }


        internal P2TransactionMessage FillMyObject()
        {
            P2TransactionMessage tMsg = new P2TransactionMessage();

            try
            {
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (UserGroupDataContext db = new UserGroupDataContext(connectionString))
                {
                    var UserGroupRights = from UserGroupRightItem in db.XSecUserRights
                                          where UserGroupRightItem.UserGroupID == this._UserGroupID
                                          && UserGroupRightItem.AccessRight == this._AccessRight
                                          && UserGroupRightItem.ModuleName == this._ModuleName
                                          select UserGroupRightItem;

                    if (UserGroupRights.Count() > 0)
                    {
                        foreach (var userGroupRight in UserGroupRights)
                        {

                            Load(userGroupRight);
                        }
                    }
                }
                tMsg.TransactionStatus = "green";
                tMsg.MessageText = "TMsg_FillMyObjectSuceeded";
            }
            catch (Exception ex) //AM:TC!!
            {
                tMsg.TransactionStatus = "red";
                tMsg.MessageText = "Error_Error";
                tMsg.MessageFreeText = ex.Message;
                P2ExceptionHandler.LogException(ex, this);
            }

            this.MessageStack.Add(tMsg);
            return tMsg;
        }

        #endregion
              

        #region Update Operations

        public P2MessageStack InsertAndUpdate(bool checkDoublicate, UserGroupDataContext db)
        {
            P2TransactionMessage tMsg = new P2TransactionMessage();

            tMsg.TransactionStatus = "green";
            P2MessageStack MessageStack = new P2MessageStack();
            
            if (tMsg.TransactionStatus == "green")
            {
                try
                {
                    if (tMsg.TransactionStatus == "green")
                    {
                        if (this.StatusID == -1) this.StatusID = 2001;
                        P2.Cuberry.Framework.Security.AccessPermissions ap = new P2.Cuberry.Framework.Security.AccessPermissions();

                        if (string.IsNullOrEmpty(this.CreatedBy)) this.CreatedBy = ap.UserID;
                        this.EditedBy = ap.UserID;

                        string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);

                        DAL.XSecUserRight editedItem;

                        var rights = from sr in db.XSecUserRights
                                     where this._UserGroupID == sr.UserGroupID && this._ModuleName == sr.ModuleName
                                     select sr;

                        if (rights.Count() == 0)
                        {
                            if (this.AccessRight > 0)
                            {
                                editedItem = new DAL.XSecUserRight()
                                {
                                    AccessRight = this.AccessRight,
                                    ModuleName = this.ModuleName,
                                    UserGroupID = this.UserGroupID,                                    

                                    //Default Fields
                                    CreatedBy = User.Current.UserID,
                                    CreatedOn = DateTime.Now,
                                    EditedBy = User.Current.UserID,
                                    EditedOn = DateTime.Now,
                                    //StatusID = this.StatusID
                                };
                                db.XSecUserRights.AddObject(editedItem);
                            }
                        }
                        else
                        {
                            editedItem = rights.First();
                            editedItem.AccessRight = this.AccessRight;
                            editedItem.ModuleName = this.ModuleName;
                            editedItem.UserGroupID = this.UserGroupID;
                            
                            //Default Fields
                            editedItem.EditedBy = User.Current.UserID;
                            editedItem.EditedOn = DateTime.Now;
                            //editedItem.StatusID = this.StatusID;

                            //track changes!
                            //this.SaveChangeLog(- No Tracking -);
                        }
                        db.SaveChanges();
                    }
                }                
                catch (Exception ex)
                {
                    MessageStack.Add(new P2TransactionMessage("red", P2Translator.GetResource("Error_Error")));
                    P2ExceptionHandler.LogException(ex, this);
                }
            }
            return MessageStack;
        }

        #endregion


        #region Copy Operations

        public UserGroupRight GetCopy()
        {
            try
            {
                UserGroupRight newItem = new UserGroupRight();
                newItem.UserGroupID = this.UserGroupID;
                newItem.ModuleName = this.ModuleName;
                newItem.AccessRight = this.AccessRight;
                newItem.ModuleName = this.ModuleName;
                newItem.Modified = this.Modified;
                return newItem;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
                return null;
            }
        }


        public void UpdateFrom(UserGroupRight sourceItem)
        {
            try
            {
                this.UserGroupID = sourceItem.UserGroupID;
                this.ModuleName = sourceItem.ModuleName;
                this.AccessRight = sourceItem.AccessRight;
                this.ModuleName = sourceItem.ModuleName;
                this.Modified = sourceItem.Modified;
            }
            catch (System.Exception ex) //AM:TC
            {
                P2ExceptionHandler.LogException(ex, string.Format("{0}.{1}", this.GetType().Name, System.Reflection.MethodInfo.GetCurrentMethod().Name));
            }
        }

        #endregion


        #region Validation
        //Empty
        #endregion

        
        #region Property Changed

        public event PropertyChangedEventHandler PropertyChanged;


        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null) Handler(this, new PropertyChangedEventArgs(propertyName));
        }


        public void OnAllPropertiesChanged()
        {
            OnPropertyChanged("UserGroupID");
            OnPropertyChanged("ModuleName");
            OnPropertyChanged("AccessRight");
            OnPropertyChanged("ActiveColor");
        }

        #endregion


        #region Validator

        public override P2Validator Validator
        {
            get
            {
                if (_validator == null)
                    _validator = new P2Validator(Properties.Settings.Default.ModuleName, this.EntityName, "UserGroupID", this);
                return _validator;
            }
        }

        #endregion


    }
}
